用node写一个Excel to Json的转换工具

写在前面

前两天一个朋友告诉我说需要我帮他写一个excel转json的工具,正好,之前在项目中也遇到了需要excel转json的情况,何不趁这次机会来做一个小工具呢。

话不多说,赶紧开干。首先我们拿到excel的文件,我直接用sublime将它打开,发现显示的居然都是二进制代码,毫无可读性。

image

但是我们从execl的输出格式上可以发现,文件可以转换为一个名叫csv的格式版本。而且这种格式是可以读取文件内容信息的。

如图,数据都显示文格式化之后的普通文本了。

image

那好,我们就选择这种格式来做。

首先我们常规的json方式来做。

也就是说,我们把表的第一段,用来表示数据字段的名称用作对象的键,而表中的具体数据作为值来表示,然后再将每一行的数据用数组串联起来就可以了。好了,话不多说,开始干。

实践

1
2
3
4
5
6
7
8

var rf = require("fs");
var data = rf.readFileSync("demo.csv", "utf-8");
var dataList = data.split("\n");

// 最后要输出的obj对象
var obj = {};
obj["data"] = [];

因为我们需要对文件进行操作,所以这里我们使用了node操作文件的模块:fs,并且使用readFileSync方法来打开demo.csv这个文件。参数utf-8表示我们打开文件所制定的文字编码格式。最后的dataList是对拿到的数据进行一个初步的处理,已换行符作为分隔,转换为一个数组。最后声明obj对象,作为我们最后转换完成的输出对象。

这里注意了,我们使用的fs模块中还有一个读取文件的方法,叫做readFile,这是一个异步的方法,而我们现在使用的readFileSync是一个同步的方法,了解js特性的开发者肯定多多少少踩过异步所带来坑,虽然在很多情况下,异步也是相当不错的解决方案,但是这里我们还是选择使用同步的readFileSync来减少一些不必要的麻烦。

1
2
3
4
5
6
7

// 建立字段名
function buildTitle() {
var _temp = dataList.splice(0, 1);
var title = _temp[0].split(",");
return title;
}

我们把数组的第一段单独拿出来作为字段名,也就是我们这里输出对象的键名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

function buildJson() {
var title = buildTitle();
var _length = title.length;
title[_length - 1] = title[_length - 1].split("\r")[0];

for (var j = 0; j < dataList.length; j++) {
var _obj = {};

if(dataList[j].length<1){
continue;
}

for (var i = 0; i < _length; i++) {
if (i == _length - 1) {
_obj[title[i]] = dataList[j].split(",")[i].split("\r")[0];
} else {
_obj[title[i]] = dataList[j].split(",")[i];
}
}
obj["data"].push(_obj);
}
}

然后通过两个循环,对所有行和每行的值进行一个遍历,然后用一个临时对象_obj来获取所有的数据,并将这个临时对象push到obj[“data”]这个对象数组中去。

注意,”title[_length - 1] = title[_length - 1].split(“\r”)[0];”这个是为了兼容不同的操作系统对换行符的定义。

1
2
3
4

if(dataList[j].length<1){
continue;
}

而这一句是为了排除空行对结果的影响(windows下面的csv导出有最底端存在无用空行的问题)。

至此,整个转换的核心就写完了,运行buildJson函数可以顺利运行,输出的obj对象也能打印出相应的数据了。但是此时的数据虽然可以用,格式却丑的可以。这里我们需要再来美化下下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// 输出json格式
function output() {
// 格式化输出json
var m = JSON.stringify(obj, null, 4);

//保存文件
rf.writeFile("result2.json", m, function (err) {
if (err) throw err;
console.log("Transform Complete"); //文件被保存
});
}

(function run() {
buildJson();
output();
})();

这里我们通过JSON对象的stringify方法来美化了下下我们的JSON对象,然后输出保存为result2.json这个文件。

结语

到这里,关于一个简单的excel to json的小工具就写完了。其实在自己动手之前,我担心写这样的小工具会不会很难,但是在实际操作过程中会发现还是很简单的,无外乎就是对数据的整理和操作。当然,首先还是要动手去尝试。

最后贴上github上的仓库地址,里面有两个案例,一个上文所说的常规格式的json转换,另外还附上了特殊格式json转换的案例。

Tips

在实际的使用过程中,因为我们是中文的使用环境,如果使用exeal保存文件为.csv的格式后,用utf-8模式解码会发现整个文件都是乱码无法使用。

image

在window的环境下很好解决,因为excel在保存中文文件时,默认采用了ansi的编码格式,只要我们在记事本中打开,然后另存为的时候选择utf-8,这样就没有乱码的问题了。

image

Excel To Json Tool